#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstdio>
#include<cstring>
using namespace std;

#define BUFF_SIZE 1000
int pipefd[2] = {0};
char *s = "hello,i am child";
char buff[BUFF_SIZE];

//从管道读
int pipe_red(){
    //sleep(100);
    int n = read(pipefd[0],buff,BUFF_SIZE);//若管道为空,则阻塞
    buff[n] = 0;
    return n;
}
//往管道写
void pipe_write(){
    int num = 5;
    //int cnt = 0;
    while(num--){
        int n = snprintf(buff,BUFF_SIZE,"%s, pid = %d, ppid = %d, num = %d",s,getpid(),getppid(),num);
        buff[n] = 0;
        write(pipefd[1],buff,strlen(buff));//若管道已经写满了,则阻塞,如果读端已经关闭,该子进程会被kill -13(SIGPIPE)掉
        //++cnt;
        //if(cnt % 100 == 0) cout<<cnt<<endl;
        sleep(1);
    }
}

int main(){
    if(pipe(pipefd) == -1){
        //创建管道失败
        perror("pipe:");
        return errno;
    }

    int id = fork();
    if(id < 0){
        perror("fork:");
        return errno;
    }else if(id == 0){
        //子进程
        close(pipefd[0]);//关闭读
        pipe_write();
        close(pipefd[1]);//通信完毕
        exit(0);
    }

    //父
    close(pipefd[1]);//关闭写
    while(1){
        if(pipe_red())cout<<buff<<endl;//防止子进程还没退出,但写端已经关闭,读0的情况
        if(waitpid(id,NULL,WNOHANG) == id) break;//子进程退出了
    }
    close(pipefd[1]);
    return 0;
}